export default class KMeans {
    constructor() {
    }

    getCode() {
        return `
//生成随机数
function getRandomNum(Min,Max) {   
    var Range = Max - Min;   
    var Rand = Math.random();   
    return(Min + Math.round(Rand * Range)); 
}

//计算欧几里德距离
function calcDis(point1, point2) {
    let dis = 0;
    if ( point1.length !== point2.length ) {
        return -1;	
    }
    point1.forEach((val, index)=>{
        dis = dis + Math.abs(point1[index] - point2[index])**2
    });
    return Math.sqrt(dis);
}

//计算所有点的平均点
function calcAverage(points) { 
    let sumX = 0, sumY = 0;
    points.forEach((point)=>{ 
        sumX = sumX + point[0];
        sumY = sumY + point[1];
    });
    return [sumX/points.length, sumY/points.length];
}

//获取数据
function getData() {
    let data = [
        {
            label: null,
            point: [2,2]
        },
        {
            label: null,
            point: [4,2]
        },
        {
            label: null,
            point: [3,4]
        },
        {
            label: null,
            point: [8,8]
        },
        {
            label: null,
            point: [10,8]
        },
        {
            label: null,
            point: [9,10]
        }
    ]
    return data;
}

//根据数据获取随机点
function getRandPoint(pointRange) {
    ranX = getRandomNum(pointRange.x.min, pointRange.x.max);
    ranY = getRandomNum(pointRange.y.min, pointRange.y.max);
    return [ranX, ranY];
}

//获取点的范围
function getPointRange(data) {
    let xRange = [];
    let yRange = [];
    data.forEach((i)=>{
        xRange.push(i.point[0]);
        yRange.push(i.point[1]);
    });
    let pointRange = {
        x: {
            min: Math.min.apply(null, xRange),
            max: Math.max.apply(null, xRange)
        },
        y: {
            min: Math.min.apply(null, yRange),
            max: Math.max.apply(null, yRange)
        }
    }
    return pointRange;
}

function kMeans(dataSet, K) {
    let pointRange = getPointRange(dataSet);
    let midPoint = [];
    Array.from({length: K}, (v, i)=>{
        midPoint.push({
            point: getRandPoint(pointRange)
        });
    });

    let isBreak = false;
    while ( !isBreak ) {

        //求点的距离并且分配给最近的质点
        dataSet.forEach((i)=>{
            let dis = 0;
            midPoint.forEach((val, index)=>{
                let tempDis = calcDis(i.point, val.point);
                if ( tempDis < dis || dis === 0) {
                    dis = tempDis;
                    i.label = index;
                }
            });
        });

        //根据所属点重新求质点
        midPoint.forEach((val, index)=>{
            let points = [],
                _points = dataSet.forEach((item)=>{
                    if ( item.label === index ) {
                        points.push(item.point);
                    }
                }),
                _point = calcAverage(points);
            if ( val.point[0] === _point[0] && val.point[1] === _point[1] ) {
                isBreak = true;
            } else {
                val.point = _point;
                isBreak = false;
            }
        });
        
    };

    console.log(JSON.stringify(midPoint));
}

kMeans(getData(), 2);
        `
    }
}